package monpkg.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.hibernate.bytecode.buildtime.ExecutionException;

import monpkg.entities.Admin;
import monpkg.entities.Promotion;
import monpkg.entities.Student;

/**
 * @author Yannick Bouchot
 * @author Jonathan Romero
 */
public class Dao implements AnnuaireDAO {

	private EntityManagerFactory factory = Persistence.createEntityManagerFactory("myBaseProject");

	/**
	 * methode permettant de creer l'entity manager
	 */
	@SuppressWarnings("unused")
	public void init() {
		Student S = new Student();
		Admin A = new Admin();
		Promotion P = new Promotion();
	}

	/**
	 * methode permettant de fermer l'entity manager
	 */
	public void close() {
		if (factory != null) {
			factory.close();
		}
	}

	/**
	 * methode permettant d'ajouter un etudiant dans la base de donnees
	 */
	/* Ajout d'un étudiant */
	public Student addStudent(Student s) {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.persist(s);
			em.getTransaction().commit();
			System.err.println("addStudent witdh id=" + s.getId());
			return (s);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant de retrouver un etudiant grace a son id dans la base
	 * de donnees
	 */
	/* Cherche une personne avec son ID */
	public Student findStudent(long id) {
		EntityManager em = null;
		Student s;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			s = em.find(Student.class, id);
			// em.getTransaction().commit();
			System.err.println("findStudent with id=" + s.getId());
			return (s);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode retournant la liste des etudiants presents dans la base de
	 * donnees
	 */
	/* Retourner la liste de tous les étudiants */
	@SuppressWarnings("unchecked")
	public List<Student> findAllStudents() {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();

			Query q = em.createNamedQuery("findAllStudentsWithName");

			System.err.println(q.getResultList());
			
			return q.getResultList();
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant la mise a jour d'un etudiant dans la base de donnees
	 */
	/* mise à jours des informations sur un etudiant */
	public Student updateStudent(Student s) {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.merge(s);
			em.getTransaction().commit();
			System.err.println("updateStudent with id=" + s.getId());
			return (s);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant la suppression d'un etudiant de la base de données
	 * grace a son id
	 */
	/* Suppression d'un Etudiant */
	public void removeStudent(long id) {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.remove(em.find(Student.class, id));
			em.getTransaction().commit();
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant l'ajout d'un administrateur
	 */
	/* Ajout d'un admistrateur */
	public Admin addAdmin(Admin a) {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.persist(a);
			em.getTransaction().commit();
			System.err.println("addStudent witdh id=" + a.getId());
			return (a);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant de trouver un administrateur grace a son id
	 */
	/* Cherche un administrateur avec son ID */
	public Admin findAdmin(long id) {
		EntityManager em = null;
		Admin a;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			a = em.find(Admin.class, id);
			// em.getTransaction().commit();
			System.err.println("findStudent with id=" + a.getId());
			return (a);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant la mise a jour d'un administrateur
	 */
	/* mise à jours des informations sur un administrateur */
	public Admin updateAdmin(Admin a) {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.merge(a);
			em.getTransaction().commit();
			System.err.println("updateStudent with id=" + a.getId());
			return (a);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant de trouver une promo et l'affiche avec ou sans les
	 * etudiants
	 */
	@Override
	public Promotion findPromotion(long id, boolean withStudents)
			throws ExecutionException {
		EntityManager em = null;
		Promotion p;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			p = em.find(Promotion.class, id);
			// em.getTransaction().commit();
			System.err.println("findpromo with id=" + p.getCode());
			return (p);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode qui renvoie la liste des promotions presentes dans la base de
	 * donnees
	 */
	/* Retourner la liste de toutes les promotions */
	@SuppressWarnings("unchecked")
	public List<Promotion> findAllPromotions() {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();

			Query q = em.createNamedQuery("findAllPromotions");

			System.err.println(q.getResultList());
			return (List<Promotion>) q.getResultList();
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant d'ajouter une promotion dans la base de donnees
	 */
	@Override
	public void addPromotion(Promotion p) throws ExecutionException {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.persist(p);
			em.getTransaction().commit();
			System.err.println("addPromo witdh id=" + p.getCode());
		} finally {
			if (em != null) {
				em.close();
			}
		}

	}

	/**
	 * methode permettant la mise a jour d'un promotion dans la base de donnees
	 */
	@Override
	public void updatePromotion(Promotion p) throws ExecutionException {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.merge(p);
			em.getTransaction().commit();
			System.err.println("updatePromo with id=" + p.getCode());
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * methode permettant la suppression d'une promotion de la base de donnees a
	 * l'aide de son id
	 */
	@Override
	public void removePromotion(long id) throws ExecutionException {
		EntityManager em = null;
		try {
			em = factory.createEntityManager();
			em.getTransaction().begin();
			// utilisation de l'EntityManager
			em.remove(em.find(Promotion.class, id));
			em.getTransaction().commit();
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}
}